﻿// ===================================
// <copyright>LogoUI Co.</copyright>
// <author>Vlad Spivak</author>
// <email>mailto:vlads@logoui.co.il</email>
// <created>20/00/10</created>
// <lastedit>20/00/10</lastedit>

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the 'Software'), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
//
// <remarks>Part of this software based on various internet sources, mostly on the works
// of members of Wpf Disciples group http://wpfdisciples.wordpress.com/
// Also project may contain code from the frameworks: 
//        Nito 
//        OpenLightGroup
//        nRoute
// </remarks>
// ====================================================================================//


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Windows;
#if !WinRT
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Interactivity;
using LogoFX.Core;
using EventTrigger = System.Windows.Interactivity.EventTrigger;

namespace LogoFX.Infra.Interactivity
{
    [Obsolete("Silverlight 4 have internal support for this")]
    public class MouseWheelTrigger
		 : TriggerBase<UIElement>
    {
        private const double DEFAULT_DELTAFACTOR = 120d;
        private static readonly Duration DURATION_ZERO = new Duration(TimeSpan.Zero);

        public static readonly DependencyProperty DeltaFactorProperty =
            DependencyProperty.Register("DeltaFactor", typeof(object), typeof(MouseWheelTrigger),
            new PropertyMetadata(DEFAULT_DELTAFACTOR, new PropertyChangedCallback(OnDeltaFactorChanged)));

        public static readonly DependencyProperty ThrottleProperty =
            DependencyProperty.Register("Throttle", typeof(Duration), typeof(MouseWheelTrigger),
            new PropertyMetadata(DURATION_ZERO));

        private IObservable<EventPattern<MouseWheelEventArgs>> _mouseWheelHandler;
        
#region Properties

        /// <summary>
        /// Factors the delta with the specified value.
        /// </summary>
        
        public double DeltaFactor
        {
            get { return Convert.ToDouble(GetValue(DeltaFactorProperty)); }
            set { SetValue(DeltaFactorProperty, value); }
        }

        
        public Duration Throttle
        {
            get { return (Duration)(GetValue(ThrottleProperty)); }
            set { SetValue(ThrottleProperty, value); }
        }

#endregion

#region Overrides

        protected override void OnAttached()
        {
            base.OnAttached();

            _mouseWheelHandler = Observable.FromEventPattern<MouseWheelEventHandler,MouseWheelEventArgs>(
                                                      (h) => AssociatedObject.MouseWheel += h,
                                                      (h) => AssociatedObject.MouseWheel -= h);

            // if throttling is required
            if (Throttle.HasTimeSpan && Throttle != TimeSpan.MaxValue && Throttle > TimeSpan.Zero)
                _mouseWheelHandler.Throttle(Throttle.TimeSpan);

            _mouseWheelHandler.Subscribe(OnMouseWheel);
        }

        protected override void OnDetaching()
        {
           base.OnDetaching();
            
           //_mouseWheelHandler.Dispose();
        }

#endregion

#region Handlers

        private void OnMouseWheel(EventPattern<MouseWheelEventArgs> e)
        {
            Double _delta = e.EventArgs.Delta / DeltaFactor;
            base.InvokeActions(_delta);
        }

        private static void OnDeltaFactorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var _newValue = Convert.ToDouble(e.NewValue);            
        }

#endregion

    }

}
#endif